﻿using Hangfire;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Serilog;

namespace WebAppHangfire.Controllers
{
    [ApiController]
    [Route("api/[controller]")]
    public class HangfireController : ControllerBase
    {

        private readonly ILogger<HangfireController> _logger;

        public HangfireController(ILogger<HangfireController> logger)
        {
            _logger = logger;
        }

        [HttpGet("TestBackgroundJob_Enqueue")]
        public async Task<ActionResult> TestBackgroundJob_Enqueue()
        {
            BackgroundJob.Enqueue(() => Log.Information("Hello world from  Hangfire!"));
            var jobId1 = BackgroundJob.Enqueue(
                () => Log.Information("执行了立即执行一次性作业"));
            return Ok("添加了一个立即执行的任务");
        }


        [HttpGet("TestBackgroundJob_Schedule")]
        public async Task<ActionResult> TestBackgroundJob_Schedule()
        {
            var jobId2 = BackgroundJob.Schedule(
                () => Log.Information("执行了延迟作业1分钟"), TimeSpan.FromMinutes(1));
            return Ok("添加了一个计划任务,延时指定时间执行");
        }

        [HttpGet("TestBackgroundJob_ContinueJobWith")]
        public async Task<ActionResult> TestBackgroundJob_ContinueJobWith()
        {
            var jobId3 = BackgroundJob.Schedule(
                () => Log.Information("执行了10秒延迟作业，当前时间：" + DateTime.Now),
                TimeSpan.FromSeconds(10));
            BackgroundJob.ContinueJobWith(
            jobId3,
                () => Log.Information("在执行了10秒延迟作业之后，又执行了延续作业，当前时间：" + DateTime.Now));

            return Ok("添加了一个持续任务");
        }

        [HttpGet("TestBackgroundJob_AddOrUpdate")]
        public async Task<ActionResult> TestBackgroundJob_AddOrUpdate()
        {
            RecurringJob.AddOrUpdate("Recurringid123", () => Log.Information("TestBackgroundJob_AddOrUpdate!123"), "0 15 10 ? * *");//每日上午10点15分
            RecurringJob.AddOrUpdate("每日10点15分", () => Log.Information("每日10点15分!"), Cron.Daily(10, 15));//每日上午10点15分
            RecurringJob.AddOrUpdate("每日10点", () => Log.Information("每日10点!"), Cron.Daily(10));//每日上午10点15分
            RecurringJob.RemoveIfExists("Recurringid123");
            RecurringJob.AddOrUpdate("每分钟", () => Log.Information("每分钟!"), Cron.Minutely);//每分
            RecurringJob.AddOrUpdate("每日", () => Log.Information("每日!"), Cron.Daily());//每分
            RecurringJob.AddOrUpdate("每8s", () => Log.Information("每8s!"), "0/8 *  * * * ?");//每8秒

            return Ok("添加了一个循环任务,定时执行");

        }


        //******************************************

        ///// <summary>
        ///// 生成图片，返回队列信息和剩余次数
        ///// </summary>
        ///// <param name="request"></param>
        ///// <returns></returns>
        ///// <exception cref="NotImplementedException"></exception>
        //public async Task<ApiResult<int?>> GenerateGraph(Form.GraphGenerationRequest request)
        //{
        //    //添加后台任务
        //    BackgroundJob.Enqueue(() => BackServiceCreateImg(request));
        //    string message = await SendWaitingCount("img-queue");
        //    return new ApiResult<int?>(HttpResultTypeEnum.Success, count - 1, message);
        //}
        ///// <summary>
        ///// 推送队列的等待信息
        ///// </summary>
        ///// <param name="enqueue">任务类型</param>
        ///// <returns></returns>
        //private async Task<string> SendWaitingCount(string enqueue)
        //{
        //    var queueLength = JobStorage.Current.GetMonitoringApi()
        //        .EnqueuedCount(enqueue);
        //    string message = $"任务已提交，您前面还有 {queueLength} 个任务正在等待。";
        //    await _hubContext.Clients.All.SendAsync("updateWaitingCount", queueLength);
        //    return message;
        //}
        /// <summary>
        /// 添加后台任务
        /// </summary>
        /// <param name="content"></param>
        /// <returns></returns>
        [HttpPost("AddBackGroundJob")]
        public JsonResult AddBackGroundJob([FromBody] string content)
        {
            try
            {
                RecurringJob.AddOrUpdate<HomeController>("AddJobController-id", x => x.Index(), "*/10 * * * * ?");

                var jobId = BackgroundJob.Schedule(() => Console.WriteLine("Delayed 10!"), TimeSpan.FromSeconds(10));
                BackgroundJob.ContinueJobWith(jobId, () => Console.WriteLine("Delayed--Continuation!"));
            }
            catch (Exception ec)
            {
            }
            return new JsonResult(new { code = 0, msg = "ok", data = "", success = true });
        }



        /// <summary>
        /// 删除一个周期任务
        /// </summary>
        /// <param name="jobname"></param>
        /// <returns></returns>
        [HttpPost("DeleteJob")]
        public JsonResult DeleteJob([FromBody] string jobname)
        {
            try
            {
                RecurringJob.RemoveIfExists(jobname);
            }
            catch (Exception ec)
            {
            }
            return new JsonResult(new { code = 0, msg = "ok", data = "", success = true });
        }
        /// <summary>
        /// 手动触发一个任务
        /// </summary>
        /// <param name="jobname"></param>
        /// <returns></returns>
        [HttpPost("TriggerRecurringJob")]
        public JsonResult TriggerRecurringJob([FromBody] string jobname)
        {
            try
            {
                RecurringJob.Trigger(jobname);
            }
            catch (Exception ec)
            {

            }
            return default;
        }

        #region 测试接口
        [HttpPost("job")]
        public AddBackgroundHangfirJobResult job()//AddBackgroundHangfirJobResult req
        {
            //try
            //{BackgroundJobCom jobname
            //    if (string.IsNullOrWhiteSpace(jobname.CronExpress))
            //    {
            //        jobname.CronExpress = "*/10 * * * * ?";
            //    }

            //    RecurringJob.AddOrUpdate<HomeController>(jobname.JobName, x => x.Index(), jobname.CronExpress);

            //    var jobId = BackgroundJob.Schedule(() => Console.WriteLine("Delayed 10!"), TimeSpan.FromSeconds(10));
            //    BackgroundJob.ContinueJobWith(jobId, () => Console.WriteLine("Delayed--Continuation!"));
            //}
            //catch (Exception ec)
            //{
            //}
            return new AddBackgroundHangfirJobResult { IsSuccess = true, ErrMessage = "", JobId = "AddJobController-id" };
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="jobname"></param>
        /// <returns></returns>
        [HttpGet("testaaa"), AllowAnonymous]
        public HangfirJobResult testaaa()
        {

            return new HangfirJobResult { IsSuccess = true };
        }
        /// <summary>
        /// 手动触发一个任务
        /// </summary>
        /// <param name="jobname"></param>
        /// <returns></returns>
        [HttpGet("testSuccess"), AllowAnonymous]
        public JsonResult testSuccess()
        {

            return new JsonResult(new { code = 0, msg = "ok-succ", data = "", success = true });
        }

        /// <summary>
        /// 手动触发一个任务
        /// </summary>
        /// <param name="jobname"></param>
        /// <returns></returns>
        [HttpGet("testFail"), AllowAnonymous]
        public JsonResult testFail()
        {
            //try
            //{
            //    RecurringJob.Trigger(jobname);
            //}
            //catch (Exception ec)
            //{

            //}
            return new JsonResult(new { code = 0, msg = "ok-fail", data = "", success = true });
        }

        #endregion
    }
    public class BackgroundJobCom
    {
        public string JobName { get; set; }
        //public List<string> Mail { get; set; }

        public int DelayFromMinutes { get; set; }
        /// <summary>
        /// 参数
        /// </summary>
        public object Data { get; set; }
        /// <summary>
        /// cron 表达式
        /// </summary>
        public string Cron { get; set; }

    }

    public class HangfirJobResult
    {
        public string? ErrMessage { get; set; }
        public bool IsSuccess { get; set; }

    }

    public class AddBackgroundHangfirJobResult : HangfirJobResult
    {
        public string JobId { get; set; }
    }
}
